home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Die Speccy' 97
/
Die Speccy' 97.iso
/
amiga_system
/
the_aminet
/
util
/
time
/
wbclock.lha
/
wbclock.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-06
|
10KB
|
427 lines
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/wb.h>
#include <proto/icon.h>
#include <proto/intuition.h>
#include <exec/devices.h>
#include <devices/timer.h>
#include <workbench/startup.h>
#include <intuition/intuition.h>
#include <dos/dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "evtypes.h"
void error(char *s)
{
struct EasyStruct es;
es.es_StructSize = sizeof(es);
es.es_Flags = 0;
es.es_Title = "WB Clock";
es.es_TextFormat = s;
es.es_GadgetFormat = "Ok";
EasyRequest(0, &es, 0, 0);
}
struct DiskObject *wb_disk_object(struct WBStartup *wbs)
{
struct WBArg *wba;
BPTR olddir;
struct DiskObject *dobj;
wba = wbs->sm_ArgList;
olddir = CurrentDir(wba[0].wa_Lock);
dobj = GetDiskObject(wba[0].wa_Name);
CurrentDir(olddir);
return dobj;
}
void wb_put_disk_object(struct WBStartup *wbs, struct DiskObject *dobj)
{
struct WBArg *wba;
BPTR olddir;
wba = wbs->sm_ArgList;
olddir = CurrentDir(wba[0].wa_Lock);
PutDiskObject(wba[0].wa_Name, dobj);
CurrentDir(olddir);
return;
}
typedef struct {
unsigned short *d;
unsigned short width, height, ww;
} drawsurface;
void draw_line(drawsurface *ds, int x1, int y1, int x2, int y2)
{
int tmp, x, y, ww;
unsigned short *d;
ww = ds->ww;
if (x2 < x1) {
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
}
if (y1 == y2) {
d = &ds->d[ww * y1];
for (; x1 <= x2; x1++) {
d[x1 >> 4] |= 1 << (15 - (x1 & 15));
}
return;
}
if (x1 == x2) {
if (y2 < y1) {
for (; y2 <= y1; y2++) {
d = &ds->d[ww * y2];
d[x1 >> 4] |= 1 << (15 - (x1 & 15));
}
} else {
for (; y1 <= y2; y1++) {
d = &ds->d[ww * y1];
d[x1 >> 4] |= 1 << (15 - (x1 & 15));
}
}
return;
}
if (y2 < y1) {
if (y1 - y2 < x2 - x1) {
for (x = x1; x <= x2; x++) {
tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
d = &ds->d[ww * tmp];
d[x >> 4] |= 1 << (15 - (x & 15));
}
} else {
for (y = y1; y >= y2; y--) {
tmp = ((y - y1) * (x2 - x1) + (y2 - y1)/2) / (y2 - y1) + x1;
d = &ds->d[ww * y];
d[tmp >> 4] |= 1 << (15 - (tmp & 15));
}
}
} else {
if (y2 - y1 < x2 - x1) {
for (x = x1; x <= x2; x++) {
tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
d = &ds->d[ww * tmp];
d[x >> 4] |= 1 << (15 - (x & 15));
}
} else {
for (y = y1; y <= y2; y++) {
tmp = ((y - y1) * (x2 - x1) + (y2 - y1)/2) / (y2 - y1) + x1;
d = &ds->d[ww * y];
d[tmp >> 4] |= 1 << (15 - (tmp & 15));
}
}
}
}
void undraw_line(drawsurface *ds, int x1, int y1, int x2, int y2)
{
int tmp, x, y, ww;
unsigned short *d;
ww = ds->ww;
if (x2 < x1) {
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
}
if (y1 == y2) {
d = &ds->d[ww * y1];
for (; x1 <= x2; x1++) {
d[x1 >> 4] &=~ (1 << (15 - (x1 & 15)));
}
return;
}
if (x1 == x2) {
if (y2 < y1) {
for (; y2 <= y1; y2++) {
d = &ds->d[ww * y2];
d[x1 >> 4] &=~ (1 << (15 - (x1 & 15)));
}
} else {
for (; y1 <= y2; y1++) {
d = &ds->d[ww * y1];
d[x1 >> 4] &=~ (1 << (15 - (x1 & 15)));
}
}
return;
}
if (y2 < y1) {
if (y1 - y2 < x2 - x1) {
for (x = x1; x <= x2; x++) {
tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
d = &ds->d[ww * tmp];
d[x >> 4] &=~ (1 << (15 - (x & 15)));
}
} else {
for (y = y1; y >= y2; y--) {
tmp = ((y - y1) * (x2 - x1) + (y2 - y1)/2) / (y2 - y1) + x1;
d = &ds->d[ww * y];
d[tmp >> 4] &=~ (1 << (15 - (tmp & 15)));
}
}
} else {
if (y2 - y1 < x2 - x1) {
for (x = x1; x <= x2; x++) {
tmp = ((x - x1) * (y2 - y1) + (x2 - x1)/2) / (x2 - x1) + y1;
d = &ds->d[ww * tmp];
d[x >> 4] &=~ (1 << (15 - (x & 15)));
}
} else {
for (y = y1; y <= y2; y++) {
tmp = ((y - y1) * (x2 - x1) + (y1 - y2)/2) / (y1 - y2) + x1;
d = &ds->d[ww * y];
d[tmp >> 4] &=~ (1 << (15 - (tmp & 15)));
}
}
}
}
void clear_circle(drawsurface *ds, int x, int y, int r)
{
int i, dx;
for (i = y - r; i <= y + r; i++) {
dx = (int)sqrt((float)(r * r - (i - y) * (i - y)));
undraw_line(ds, x - dx, i, x + dx, i);
}
}
void draw_radius(drawsurface *d1, drawsurface *d2, int x, int y, int r, double theta)
{
int x2, y2, dx, dy;
double rcos, rsin;
rcos = r * cos(theta);
rsin = r * sin(theta);
x2 = (int)rcos + x;
y2 = -(int)rsin + y;
if (abs(rsin) > abs(rcos)) {
dx = 1;
dy = 0;
} else {
dx = 0;
dy = 1;
}
draw_line(d1, x + dx, y + dy, x2 + dx, y2 + dy);
undraw_line(d2, x + dx, y + dy, x2 + dx, y2 + dy);
draw_line(d2, x, y, x2, y2);
undraw_line(d1, x, y, x2, y2);
}
void clear_clock(struct DiskObject *dobj)
{
struct Gadget *g;
struct Image *i1, *i2;
drawsurface d1a, d1b, d2a, d2b;
g = &dobj->do_Gadget;
i1 = (struct Image *)g->GadgetRender;
i2 = (struct Image *)g->SelectRender;
d1a.width = i1->Width;
d1a.height = i1->Height;
d1a.ww = (i1->Width + 15) / 16;
d2a.width = i2->Width;
d2a.height = i2->Height;
d2a.ww = (i2->Width + 15) / 16;
d1b = d1a;
d2b = d2a;
d1a.d = i1->ImageData;
d2a.d = i2->ImageData;
d1b.d = d1a.d + d1a.height * d1a.ww;
d2b.d = d2a.d + d2a.height * d2a.ww;
clear_circle(&d1a, d1a.width / 2, d1a.height / 2, 15);
clear_circle(&d1b, d1b.width / 2, d1b.height / 2, 15);
clear_circle(&d2a, d2a.width / 2 + 1, d2a.height / 2 + 1, 15);
clear_circle(&d2b, d2b.width / 2 + 1, d2b.height / 2 + 1, 15);
}
void draw_time(struct timerequest *tr, struct DiskObject *dobj)
{
int hours, mins;
struct Gadget *g;
struct Image *i1, *i2;
drawsurface d1a, d1b, d2a, d2b;
double mtheta, htheta;
mins = (tr->tr_time.tv_secs / 60) % 60;
hours = (tr->tr_time.tv_secs / 60) % 720;
g = &dobj->do_Gadget;
i1 = (struct Image *)g->GadgetRender;
i2 = (struct Image *)g->SelectRender;
d1a.width = i1->Width;
d1a.height = i1->Height;
d1a.ww = (i1->Width + 15) / 16;
d2a.width = i2->Width;
d2a.height = i2->Height;
d2a.ww = (i2->Width + 15) / 16;
d1b = d1a;
d2b = d2a;
d1a.d = i1->ImageData;
d2a.d = i2->ImageData;
d1b.d = d1a.d + d1a.height * d1a.ww;
d2b.d = d2a.d + d2a.height * d2a.ww;
mtheta = PID2 - 2 * PI * mins / 60;
htheta = PID2 - 2 * PI * hours / 720;
clear_circle(&d1a, d1a.width / 2, d1a.height / 2, 15);
clear_circle(&d1b, d1b.width / 2, d1b.height / 2, 15);
clear_circle(&d2a, d2a.width / 2 + 1, d2a.height / 2 + 1, 15);
clear_circle(&d2b, d2b.width / 2 + 1, d2b.height / 2 + 1, 15);
draw_radius(&d1a, &d1b, d1b.width / 2, d1b.height / 2, 14, mtheta);
draw_radius(&d1a, &d1b, d1b.width / 2, d1b.height / 2, 8, htheta);
draw_radius(&d2a, &d2b, d1b.width / 2 + 1, d1b.height / 2 + 1, 14, mtheta);
draw_radius(&d2a, &d2b, d1b.width / 2 + 1, d1b.height / 2 + 1, 8, htheta);
}
#define DIE_MESSAGE 0xaaff
void main(int argc, char **argv)
{
struct DiskObject *dobj;
struct MsgPort *timeport;
struct timerequest *timer, *intr;
boolean quit = false;
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
if (!IntuitionBase) {
exit(15);
}
if (timeport = FindPort("wb_clock")) {
timer = (struct timerequest *)CreateExtIO(timeport, sizeof(*timer));
if (!timer) {
error("Can't create time request");
CloseLibrary((struct Library *)IntuitionBase);
exit(10);
}
timer->tr_node.io_Command = DIE_MESSAGE;
PutMsg(timeport, (struct Message *)timer);
CloseLibrary((struct Library *)IntuitionBase);
exit(0);
}
IconBase = OpenLibrary("icon.library", 0);
if (!IconBase) {
error("Can't open icon.library");
CloseLibrary((struct Library *)IntuitionBase);
exit(10);
}
WorkbenchBase = OpenLibrary("workbench.library", 0);
if (WorkbenchBase) {
if (argc) dobj = GetDiskObject(argv[0]);
else dobj = wb_disk_object((struct WBStartup *)argv);
if (dobj) {
timeport = CreatePort("wb_clock", 0);
if (timeport) {
timer = (struct timerequest *)CreateExtIO(timeport, sizeof(*timer));
if (timer) {
if (OpenDevice("timer.device", UNIT_VBLANK, (void *)timer, 0) == 0) {
timer->tr_node.io_Command = TR_ADDREQUEST;
timer->tr_time.tv_secs = 5;
timer->tr_time.tv_micro = 0;
SendIO((void *)timer);
while (1) {
Wait(1 << timeport->mp_SigBit);
while (intr = (struct timerequest *)GetMsg(timeport)) {
if (intr->tr_node.io_Command == DIE_MESSAGE) {
quit = true;
DeleteExtIO((void *)intr);
AbortIO((void *)timer);
continue;
}
if (quit) {
clear_clock(dobj);
if (argc) PutDiskObject(argv[0], dobj);
else wb_put_disk_object((struct WBStartup *)argv, dobj);
error("Exiting ...");
goto quit_loop;
}
timer->tr_node.io_Command = TR_GETSYSTIME;
DoIO((void *)timer);
draw_time(timer, dobj);
if (argc) PutDiskObject(argv[0], dobj);
else wb_put_disk_object((struct WBStartup *)argv, dobj);
timer->tr_node.io_Command = TR_ADDREQUEST;
timer->tr_time.tv_secs = 60 - timer->tr_time.tv_secs % 60;
timer->tr_time.tv_micro = 0;
SendIO((void *)timer);
}
}
quit_loop:
CloseDevice((void *)timer);
} else error("Can't open timer.device");
DeleteExtIO((void *)timer);
} else error("Can't create timer request");
DeletePort(timeport);
} else error("Can't create port");
FreeDiskObject(dobj);
} else error("Can't get disk object");
CloseLibrary(WorkbenchBase);
} else error("Can't open workbench.library");
CloseLibrary(IconBase);
CloseLibrary((struct Library *)IntuitionBase);
}